home *** CD-ROM | disk | FTP | other *** search
/ CD Exchange / CD Exchange - Volume 1.iso / graphics / utils / ham8-jpeg / source / ham8.c < prev    next >
C/C++ Source or Header  |  1992-12-20  |  11KB  |  460 lines

  1. /*
  2.  * ham8.c Michael Saunby   M.Saunby@reading.ac.uk
  3.  *
  4.  * Release 1.1   December 1992 A public screen plus utilities to give a pseudo
  5.  * 24 bit display on Amigas with AGA graphics (A1200 and A4000).
  6.  *
  7.  * The AGA HAM-8 mode allows 64 colours to be defined - 48 of these will be
  8.  * defined by this program (see display24.c) leaving 8 for intuition and
  9.  * client programs.
  10.  */
  11. #include <intuition/intuition.h>
  12. #include <graphics/gfxbase.h>
  13. #include <graphics/displayinfo.h>
  14. #include <intuition/screens.h>
  15. #include <dos/dosextens.h>
  16. #include <dos/rdargs.h>
  17. #include <exec/memory.h>
  18. #include <exec/types.h>
  19. #include <libraries/dos.h>
  20. #include <libraries/dosextens.h>
  21. #include <libraries/gadtools.h>
  22.  
  23. #include <clib/exec_protos.h>
  24. #include <clib/intuition_protos.h>
  25. #include <clib/graphics_protos.h>
  26. #include <clib/gadtools_protos.h>
  27. #include <clib/dos_protos.h>
  28. #include <clib/alib_protos.h>
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32.  
  33. #include "display24.h"
  34.  
  35. /*
  36.  * If you turn this into something different feel free to change this, but if
  37.  * you don't leave it alone!!
  38.  */
  39. #define COPYRIGHT_MESSAGE "Version 1.1\nDecember 1992\n\nCopyright © 1992\n\
  40. Michael Saunby"
  41.  
  42. /*
  43.  * Template etc for ReadArgs() - Pity it can't read tooltypes
  44.  */
  45. #define TEMPLATE "W=Width/N,H=Height/N,L=LoRes/S"
  46. #define OPT_WIDTH 0
  47. #define OPT_HEIGHT 1
  48. #define OPT_LORES 2
  49. #define OPT_COUNT 3
  50.  
  51. struct IntuitionBase *IntuitionBase = NULL;
  52. struct GfxBase *GfxBase = NULL;
  53. struct Library *GadToolBase = NULL;
  54.  
  55. extern struct ExecBase *SysBase;
  56.  
  57. BOOL restart = FALSE;        /* used for resize - see main() */
  58. UWORD width, height;
  59. BOOL lores;
  60. struct Screen *screen;
  61. struct MsgPort *messageport;
  62. ULONG allocsignal;
  63.  
  64. /*
  65.  * Message structure used to get screen size changed, see main()
  66.  */
  67. struct TestMsg
  68. {
  69.   struct Message msg;
  70.   USHORT Width;
  71.   USHORT Height;
  72.   BOOL Lores;
  73. };
  74.  
  75. /*
  76.  * Easy Requester used for error messages
  77.  */
  78. struct EasyStruct failedES =
  79. {sizeof (struct EasyStruct), 0, HAM8_ALBERT_NAME,
  80.  "%s", "OK",};
  81.  
  82. /*
  83.  * Gadtools menu
  84.  */
  85. #define ABOUT 1
  86. #define QUIT 2
  87. struct NewMenu prj_menu[] =
  88. {
  89.   {NM_TITLE, "Project", 0, 0, 0, 0,},
  90.   {NM_ITEM, "About...", "?", 0, 0, (void *) ABOUT,},
  91.   {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
  92.   {NM_END, NULL, 0, 0, 0, 0,},
  93. };
  94.  
  95.  
  96. /*
  97.  * Cleanup() - Close screen and libraries before exit
  98.  */
  99. VOID Cleanup (VOID);
  100.  
  101. VOID
  102. Cleanup ()
  103. {
  104.   if (restart)
  105.     {
  106.       /*
  107.        * Failed to open screen for client. There is a message port waiting
  108.        * for a reply.
  109.        */
  110.     }
  111.   if (screen)
  112.     {
  113.       CloseScreen (screen);
  114.       FreeSignal (allocsignal);
  115.     }
  116.   if (GadToolBase)
  117.     CloseLibrary (GadToolBase);
  118.   if (IntuitionBase)
  119.     CloseLibrary ((struct Library *) IntuitionBase);
  120.   if (GfxBase)
  121.     CloseLibrary ((struct Library *) GfxBase);
  122.  
  123. }
  124.  
  125. /*
  126.  * Quit() - Cleanup and exit on error
  127.  */
  128. VOID Quit ();
  129.  
  130. VOID
  131. Quit (char whytext[], UBYTE failcode)
  132. {
  133.   EasyRequest (NULL, &failedES, NULL, whytext);
  134.   Cleanup ();
  135.   DeletePort (messageport);
  136.   exit (failcode);
  137. }
  138.  
  139. /*
  140.  * CreateScreen() - Main function, build and open a public screen
  141.  */
  142. VOID
  143. CreateScreen ( /* USES GLOBALS width, height, lores, restart */ )
  144. {
  145.   ULONG modeID = HIRESHAMLACE_KEY;
  146.   DisplayInfoHandle displayhandle;
  147.   struct DimensionInfo dimensioninfo;
  148.  
  149.   UWORD maxdepth;
  150.   ULONG soerror = NULL;
  151.   ULONG signal, wsignal, lastsignal;
  152.   ULONG psignal;        /* Message port - Another copy of program
  153.                  * started */
  154.   struct Task *task;
  155.   BOOL abort = FALSE, closedown = FALSE;
  156.   UWORD oldstatus;
  157.   struct IntuiMessage *msg;
  158.   static struct TestMsg *newdims_msg;    /* MUST be static, reply is delayed! */
  159.   struct Window *window;
  160.   struct Menu *menu;
  161.   void *vi;
  162.  
  163.  
  164.   if (lores)
  165.     modeID = HAM_KEY;
  166.  
  167.   if ((GfxBase =
  168.        (struct GfxBase *) OpenLibrary ("graphics.library", 36)) == NULL)
  169.     Quit ("graphics.library is too old <V36", 25);
  170.  
  171.   if ((IntuitionBase =
  172.     (struct IntuitionBase *) OpenLibrary ("intuition.library", 36)) == NULL)
  173.     Quit ("intuition.library is too old <V36", 25);
  174.  
  175.   if ((displayhandle = FindDisplayInfo (modeID)) == NULL)
  176.     Quit ("modeID not found in display database", 25);
  177.  
  178.   if (GetDisplayInfoData (displayhandle, (UBYTE *) & dimensioninfo,
  179.                sizeof (struct DimensionInfo), DTAG_DIMS, NULL) == 0)
  180.     Quit ("mode dimension info not available", 25);
  181.  
  182.   /*
  183.    * Public screen needs a signal and pointer to this task.
  184.    */
  185.   if ((allocsignal = AllocSignal (-1)) == -1)
  186.     Quit ("could not allocate signal", 25);
  187.  
  188.   lastsignal = 1 << allocsignal;
  189.  
  190.   task = (struct Task *) & ((struct Process *) FindTask (NULL))->pr_Task;
  191.  
  192.   /*
  193.    * MaxDepth will always be 8 for Ham8 mode.  But it can't hurt.
  194.    */
  195.   maxdepth = dimensioninfo.MaxDepth;
  196.   /*
  197.    * If you always want a standard size just use SA_Overscan, OSCAN_TEXT
  198.    * etc.  I have to get the dimensions from dimensioninfo because I always
  199.    * set the width and height.
  200.    */
  201.   if (width == 0)
  202.     width = dimensioninfo.TxtOScan.MaxX - dimensioninfo.TxtOScan.MinX;
  203.   if (height == 0)
  204.     height = dimensioninfo.TxtOScan.MaxY - dimensioninfo.TxtOScan.MinY;
  205.  
  206.   /*
  207.    * Screen is based on workbech to give a familiar look. Could possibly
  208.    * cause problems is the default is a 256 colour WB, must try that
  209.    * sometime and see what happens.
  210.    */
  211.   if ((screen = OpenScreenTags (NULL,
  212.                 SA_LikeWorkbench, TRUE,    /* see above */
  213.                 SA_Overscan, OSCAN_TEXT,
  214.                 SA_AutoScroll, TRUE,
  215.                 SA_DisplayID, modeID,
  216.                 SA_Depth, (UBYTE) maxdepth,
  217.                 SA_Width, width,
  218.                 SA_Height, height,
  219.                 SA_Title, HAM8_ALBERT_NAME,
  220.                 SA_PubName, HAM8_ALBERT_NAME,
  221.                 SA_PubSig, allocsignal,
  222.                 SA_PubTask, task,
  223.                 SA_ErrorCode, &soerror,
  224.                 SA_SharePens, TRUE,
  225.                 TAG_END)) == NULL)
  226.     {
  227.       /*
  228.        * There are many reasons why this might fail, though on an AGA
  229.        * machine only NOCHIPMEM is likely.  The other tests are worth
  230.        * keeping for when this code is next used.
  231.        */
  232.       switch (soerror)
  233.     {
  234.     case OSERR_NOCHIPS:
  235.       Quit ("Amiga custom chips not AGA", 25);
  236.       break;
  237.  
  238.     case OSERR_UNKNOWNMODE:
  239.       Quit ("Cannot open screen in this mode", 25);
  240.       break;
  241.  
  242.     case OSERR_NOCHIPMEM:
  243.       Quit ("Not enough CHIP memory", 25);
  244.       break;
  245.  
  246.     case OSERR_NOMEM:
  247.       Quit ("Not enough memory (CHIP or FAST)", 25);
  248.       break;
  249.  
  250.     default:
  251.       Quit ("Unspecified error opening screen", 25);
  252.       break;
  253.     }
  254.     }
  255.   /*
  256.    * StandardPalette() returns number of errors (see display24.c) I ignore
  257.    * the errors here and leave it to the client programs to deal with.
  258.    */
  259.   (VOID) StandardPalette (&(screen->ViewPort), FALSE);
  260.  
  261.   if ((menu = CreateMenus (prj_menu, GTMN_FrontPen, 1, TAG_DONE)) == NULL)
  262.     Quit ("could not build menu", 25);
  263.  
  264.   /*
  265.    * Open a backdrop window to which the above menu is attached.
  266.    */
  267.   if ((window = OpenWindowTags (NULL,
  268.                 WA_Top, screen->BarHeight + 1,
  269.                 WA_Height, screen->Height -
  270.                 (screen->BarHeight + 1),
  271.                 WA_CustomScreen, screen,
  272.                 WA_NewLookMenus, TRUE,
  273.                 WA_IDCMP, MENUPICK,
  274.          WA_Flags, ACTIVATE | BACKDROP | BORDERLESS | NOCAREREFRESH,
  275.                 TAG_END)) == NULL)
  276.     Quit ("could not open backdrop window", 25);
  277.  
  278.   /*
  279.    * visual info need to get proper look for menu
  280.    */
  281.   vi = GetVisualInfo (screen, TAG_END);
  282.   if (LayoutMenus (menu, vi, TAG_DONE) == NULL)
  283.     Quit ("could not layout menu", 25);
  284.   FreeVisualInfo (vi);
  285.   SetMenuStrip (window, menu);
  286.  
  287.   /*
  288.    * now go public
  289.    */
  290.   oldstatus = PubScreenStatus (screen, 0);
  291.  
  292.  
  293.   /*
  294.    * come forward if and window opens on this screen
  295.    */
  296.   SetPubScreenModes (POPPUBSCREEN);
  297.  
  298.   if (restart)
  299.     {
  300.       ReplyMsg ((struct Message *) newdims_msg);
  301.       restart = FALSE;
  302.     }
  303.   /*
  304.    * Now wait until told to quit by user (from menu) waiting of course for
  305.    * any visitors to leave.
  306.    */
  307.   psignal = 1 << messageport->mp_SigBit;
  308.   wsignal = 1 << window->UserPort->mp_SigBit;
  309.  
  310.   do
  311.     {
  312.       signal = Wait (wsignal | lastsignal | psignal);
  313.       if (signal & psignal)
  314.     {
  315.       newdims_msg = (struct TestMsg *) GetMsg (messageport);
  316.       width = newdims_msg->Width;
  317.       height = newdims_msg->Height;
  318.       lores = newdims_msg->Lores;
  319.       restart = TRUE;
  320.       /* NB. no reply to message until we have new screen */
  321.       if ((oldstatus = PubScreenStatus (screen,
  322.                         PSNF_PRIVATE)) & 1)
  323.         {
  324.           abort = TRUE;
  325.         }
  326.       els